/**
 * 
 */
package com.ztesoft.web.taskgenerator.service.impl;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.stereotype.Service;

import com.ztesoft.core.cache.EhCacheService;
import com.ztesoft.core.common.Page;
import com.ztesoft.core.convert.IArgConversionService;
import com.ztesoft.core.db.ds.DynamicDataSourceManager;
import com.ztesoft.core.idproduce.ISequenceGenerator;
import com.ztesoft.framework.exception.BaseAppException;
import com.ztesoft.framework.log.ZTEsoftLogManager;
import com.ztesoft.framework.util.DateUtils;
import com.ztesoft.framework.util.StringUtils;
import com.ztesoft.framework.util.Utils;
import com.ztesoft.web.baseconfig.db.arg.SubTableDefineArg;
import com.ztesoft.web.baseconfig.db.dao.DmDataStateDao;
import com.ztesoft.web.baseconfig.db.dao.DmPlanDao;
import com.ztesoft.web.baseconfig.db.dao.DmPlanRelationDao;
import com.ztesoft.web.baseconfig.db.dao.DmSrcTableDao;
import com.ztesoft.web.baseconfig.db.dao.DmStrategyDao;
import com.ztesoft.web.baseconfig.db.dao.DmTargetTableDao;
import com.ztesoft.web.baseconfig.db.dao.SubTableDefineDao;
import com.ztesoft.web.baseconfig.db.po.DmDataStatePO;
import com.ztesoft.web.baseconfig.db.po.DmPlanPO;
import com.ztesoft.web.baseconfig.db.po.DmPlanRelationPO;
import com.ztesoft.web.baseconfig.db.po.DmSrcTablePO;
import com.ztesoft.web.baseconfig.db.po.DmStrategyPO;
import com.ztesoft.web.baseconfig.db.po.DmTargetTablePO;
import com.ztesoft.web.baseconfig.db.po.SubTableDefinePO;
import com.ztesoft.web.cleanup.service.CleanUpService;
import com.ztesoft.web.common.DMSConstant;
import com.ztesoft.web.common.Util;
import com.ztesoft.web.common.customdb.dao.DmSrcTableCustomDao;
import com.ztesoft.web.common.customdb.dao.DmTaskStageCustomDao;
import com.ztesoft.web.common.db.arg.DmArg;
import com.ztesoft.web.common.db.arg.SysModuleArg;
import com.ztesoft.web.common.db.arg.SysModuleArg.SysModuleCriteria;
import com.ztesoft.web.common.db.dao.DbBaseInfoDao;
import com.ztesoft.web.common.db.dao.DmDao;
import com.ztesoft.web.common.db.dao.SysModuleDao;
import com.ztesoft.web.common.db.dao.SysParamDao;
import com.ztesoft.web.common.db.po.DbBaseInfoPO;
import com.ztesoft.web.common.db.po.DmPO;
import com.ztesoft.web.common.db.po.SysModulePO;
import com.ztesoft.web.common.exchange.ExchangeFunc;
import com.ztesoft.web.common.vo.TaskNotify;
import com.ztesoft.web.filecommon.db.arg.DmFDetailArg;
import com.ztesoft.web.filecommon.db.dao.DmFDao;
import com.ztesoft.web.filecommon.db.dao.DmFDetailDao;
import com.ztesoft.web.filecommon.db.po.DmFDetailPO;
import com.ztesoft.web.filecommon.db.po.DmFPO;
import com.ztesoft.web.syncbaseinfo.service.BaseInfoService;
import com.ztesoft.web.taskgenerator.db.arg.DmTaskArg;
import com.ztesoft.web.taskgenerator.db.arg.DmTaskArg.DmTaskCriteria;
import com.ztesoft.web.taskgenerator.db.arg.DmTaskStageArg;
import com.ztesoft.web.taskgenerator.db.arg.DmTaskStageArg.DmTaskStageCriteria;
import com.ztesoft.web.taskgenerator.db.dao.DmTaskDao;
import com.ztesoft.web.taskgenerator.db.dao.DmTaskStageDao;
import com.ztesoft.web.taskgenerator.db.po.DmTaskPO;
import com.ztesoft.web.taskgenerator.db.po.DmTaskStagePO;
import com.ztesoft.web.taskgenerator.service.IDmTaskService;
import com.ztesoft.web.taskgenerator.service.IDmTaskStageService;
import com.ztesoft.web.taskgenerator.taskjob.DmHandTask;
import com.ztesoft.web.taskscheduling.service.TaskExecchildThreadService;

/**
 * <Description> <br>
 * 
 * @author codeCreater<br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2014年11月11日 <br>
 * @since V1.0<br>
 * @see com.ztesoft.web.taskgenerator.service.impl <br>
 */

@Service("dmTaskStageService")
public class DmTaskStageServiceImpl implements IDmTaskStageService {

	private static final ZTEsoftLogManager logger = ZTEsoftLogManager
			.getLogger(DmTaskStageServiceImpl.class);

	@Autowired
	private DmTaskStageDao dmTaskStageDao;
	@Autowired
	private DmPlanRelationDao dmPlanRelationDao;
	@Autowired
	private DmTaskDao dmTaskDao;
	@Autowired
	private DmTaskStageCustomDao dmTaskStageCustomDao;
	@Autowired
	private SysParamDao sysParamDao;
	@Autowired
	private DmPlanDao dmPlanDao;
	@Autowired
	private DmDao dmDao;
	@Autowired
	private TaskExecchildThreadService taskExecchildThreadService;
	@Autowired
	private IDmTaskService dmTaskService;
	@Autowired
	private DmHandTask dmHandTask;
	@Autowired
	private SysModuleDao sysModuleDao;
	@Autowired
	private DmDataStateDao dmDataStateDao;
	@Autowired
	private DmSrcTableDao dmSrcTableDao;
	@Autowired
	private DmStrategyDao dmStrategyDao;
	@Autowired
	private DmTargetTableDao dmTargetTableDao;
	@Autowired
	private DbBaseInfoDao dbBaseInfoDao;
	@Autowired
	private BaseInfoService baseInfoService;
	@Autowired
	private DynamicDataSourceManager dynamicDataSourceManager;// 数据库连接
	@Autowired
	private SubTableDefineDao subTableDefineDao;//分表定义
	@Autowired
	private ExchangeFunc exchangeFunc;//转换方法
	@Autowired
	private DmSrcTableCustomDao srcTableCustomDao;
	@Autowired
	private CleanUpService cleanUpService;//清理接口
	@Autowired
	private DmFDetailDao dmFDetailDao;
	@Autowired
	private DmFDao dmFDao;
	
	@Resource(name = "frameworkEhCacheService")
	private EhCacheService dmsCacheService;
	
	/**
	 * 查询条件转换成Arg类的服务接口
	 */
	@Resource(name = "defaultArgConversionService")
	private IArgConversionService argConversionService;

	/**
	 * 主键生成器
	 */
	@Resource(name = "sequenceProcGenerator")
	private ISequenceGenerator sequenceGenerator;

	@Override
	public DmTaskStagePO selectByPrimaryKey(Integer key)
			throws BaseAppException {
		return dmTaskStageDao.selectByPrimaryKey(key);
	}

	@Override
	public List<DmTaskStagePO> selectByArg(DmTaskStagePO record)
			throws BaseAppException {
		logger.debug("selectByArg begin...record={0}", record);
		DmTaskStageArg arg = argConversionService.invokeArg(
				DmTaskStageArg.class, record);
		return dmTaskStageDao.selectByArg(arg);
	}

	@Override
	public Page<DmTaskStagePO> selectByArgAndPage(DmTaskStagePO record,
			Page<DmTaskStagePO> resultPage) throws BaseAppException {
		logger.debug("selectByArgAndPage begin...record={0}", record);

		DmTaskStageArg arg = argConversionService.invokeArg(
				DmTaskStageArg.class, record);

		resultPage = dmTaskStageDao.selectByArgAndPage(arg, resultPage);

		return resultPage;
	}

	@Override
	public int add(DmTaskStagePO record) throws BaseAppException {
		logger.debug("add begin...record={0}", record);


		return dmTaskStageDao.insertSelective(record);
	}

	@Override
	public int update(DmTaskStagePO record) throws BaseAppException {
		logger.debug("update begin...record={0}", record);


		return dmTaskStageDao.updateByPrimaryKeySelective(record);
	}

	@Override
	public int delete(DmTaskStagePO record) throws BaseAppException {
		logger.debug("delete begin...record={0}", record);


		return dmTaskStageDao.deleteByPrimaryKey(record.getDmInfoId());
	}

	@Override
	public Page<DmTaskStagePO> selectListByArg(DmTaskStagePO record,
			Page<DmTaskStagePO> resultPage){
		logger.debug("selectListByArg begin...record={0}", record);
		DmTaskStageArg arg = new DmTaskStageArg();
		DmTaskStageCriteria criteria = arg.createCriteria();
		criteria.andConStateEqualTo("00A");
		List<Integer> goingDetail;
		List<DmTaskStagePO> stagePOList = new ArrayList<DmTaskStagePO>();
		if (Utils.isEmpty(record.getPlanName())
				&& Utils.isEmpty(record.getState())
				&& Utils.isEmpty(record.getNodeId())
				&& Utils.isEmpty(record.getStage())
				&& Utils.isEmpty(record.getScheduleDateStart())
				&& Utils.isEmpty(record.getScheduleDateEnd())) {
			stagePOList = dmTaskStageDao.selectAllListByArg(arg, resultPage);
			// 计划维护更新执行<自动2手工>状态时，修改~2016/01/05 lwb
			for (DmTaskStagePO dmTaskStagePO : stagePOList) {
				if (dmTaskStagePO.getPriority()!= null && dmTaskStagePO.getPlanExecType().equals("2")
						&& dmTaskStagePO.getPlanExecType().equals(dmTaskStagePO.getPriority())) {
					dmTaskStagePO.setPriority(null);
					dmTaskStagePO.setDmTaskId(null);
					dmTaskStagePO.setTaskName(null);
					dmTaskStagePO.setTaskCheck(null);
					dmTaskStagePO.setTaskDetail(null);
					dmTaskStagePO.setTaskState(null);
					dmTaskStagePO.settCount(0);
					dmTaskStagePO.setrCount(0);
					dmTaskStagePO.setaCount(0);
					dmTaskStagePO.setfCount(0);
					dmTaskStagePO.setxCount(0);
					dmTaskStagePO.setTotal(0);
					dmTaskStagePO.setTaskStartTime(null);
					dmTaskStagePO.setTaskEndTime(null);
					dmTaskStagePO.setExecType("2");
				}
			}
		}else {
			if (Utils.notEmpty(record.getPlanName())) {
				criteria.andPlanNameLike(StringUtils.trim(record.getPlanName()));
			}
			if (Utils.notEmpty(record.getState())) {
				criteria.andTaskStateEqualTo(record.getState());
			}
			if (Utils.notEmpty(record.getNodeId())) {
				//遍历需要的节点——开始
			       List<Integer> resultIdList = new ArrayList<Integer>();//删除id
			       List<Integer> idList = new ArrayList<Integer>();//查找id
			       idList.add(record.getNodeId());//作父节点去查
			       List<SysModulePO> sysModulePOList  = null;
				        while(true) {
				        	 if (idList.size() == 0) break;
				        	 SysModuleArg arg1 = new SysModuleArg();
				        	 SysModuleCriteria criteria1 = arg1.createCriteria();
				        	 criteria1.andParentModuleIdIn(idList);
				             sysModulePOList =sysModuleDao.selectByParentModuleIdTree(arg1);//IN idList
				        	 if (sysModulePOList.size() == 0) {//加外部传入的值
				        		 resultIdList.add(record.getNodeId());
				        		 break;
				        	 } else {
				        		 idList = new ArrayList<Integer>();//id
				        		 for (SysModulePO spo : sysModulePOList)  {
				        			 resultIdList.add(spo.getModuleId());// 放到list1
				        			 idList.add(spo.getModuleId());
				        		 }
				        	 }
				        }
			      //遍历需要的节点——结束
				//criteria.andNodeIdIn(resultIdList);
				criteria.andConNodeIdIn(resultIdList);
			}
			if (Utils.notEmpty(record.getStage())) {
				criteria.andConStageEqualTo((record.getStage()));
			}

			if (Utils.notEmpty(record.getScheduleDateStart())
					|| Utils.notEmpty(record.getScheduleDateEnd())) {
				if ("".equals(record.getScheduleDateStart())
						&& !"".equals(record.getScheduleDateEnd())) {
					criteria.andScheduleDateLessThanOrEqualTo(record.getScheduleDateEnd());
				} else if (!"".equals(record.getScheduleDateStart())
						&& "".equals(record.getScheduleDateEnd())) {
					criteria.andScheduleDateGreaterThanOrEqualTo(record.getScheduleDateStart());
				} else if (!"".equals(record.getScheduleDateStart())
						&& !"".equals(record.getScheduleDateEnd())) {
					criteria.andScheduleDateLessThan(DateUtils.getNextDate(record.getScheduleDateEnd()));
					criteria.andScheduleDateGreaterThanOrEqualTo(record.getScheduleDateStart());
//						criteria.andScheduleDateBetween(
//								sdf.parse(record.getScheduleDateStart()),
//								sdf.parse(record.getScheduleDateEnd()));
				}
				//arg.or(criteriaNew.andScheduleDateIsNull());

			}
			stagePOList = dmTaskStageDao.selectListByArg(arg, resultPage);
		}

		// 策略明细

		// 执行细节
		for (DmTaskStagePO dmTaskStagePO : stagePOList) {
			goingDetail = new ArrayList<Integer>();
			goingDetail.add(0, dmTaskStagePO.getTotal());
			goingDetail.add(1, dmTaskStagePO.getaCount());
			goingDetail.add(2, dmTaskStagePO.getrCount());
			goingDetail.add(3, dmTaskStagePO.gettCount());
			goingDetail.add(4, dmTaskStagePO.getfCount());
			dmTaskStagePO.setGoingDetail(goingDetail);
//			System.out.println(dmTaskStagePO.getTaskDetail());
			if (!Utils.isEmpty(dmTaskStagePO.getTaskDetail())) {
				List<String> detail = Utils.removeDuplicate(Utils
						.convertIdString2ListByComma(dmTaskStagePO
								.getTaskDetail()));
				dmTaskStagePO.setMonitorDetail(detail);
				dmTaskStagePO.setStrategyCount(detail.size());
			}
		}
		resultPage.setResultList(stagePOList);
		return resultPage;
	}

	@Override
	public Page<DmTaskStagePO> selectListInfo(Integer dmTaskId, String state,
    		Page<DmTaskStagePO> resultListPage) throws BaseAppException {
		logger.debug("selectListInfo begin...dmTaskId={0}", dmTaskId);
		return dmTaskStageDao.selectListInfo(dmTaskId, state,resultListPage);
	}

	@Override
	public List<String> startTask(String dmPlanIdStr) {
		logger.info("========启动任务执行============||计划ID{0}",dmPlanIdStr);
		StringBuilder msgBuilder = new StringBuilder();//计划执行处理消息
		//遍历处理计划
		DmPlanPO  planPO = null;
		for (String planIdStr : Utils.convertIdString2ListByComma(dmPlanIdStr)) {
			planPO = dmPlanDao.selectByPrimaryKey(Integer.valueOf(planIdStr));
			if (isDoRecovery(msgBuilder, planPO) || !isValid(msgBuilder, planPO)) {
				continue;
			}
//			List<DmTaskPO> taskList = getTaskList(msgBuilder, planPO);
			
			List<DmTaskPO> taskList = dmTaskDao.selectTaskPOByPlanIdStart(planPO.getDmPlanId());
			if(Utils.isEmpty(taskList) && Util.isHanderTask(planPO.getExecType())){
				msgBuilder.append(dmHandTask.initTableName(planPO.getDmPlanId(), null));
			}else{
				executeTask(msgBuilder, planPO, taskList);   
			}
		}
		logger.info("========启动任务执行ok============");
		return stringToList(msgBuilder.toString());

	}

	/**
	 * 启动执行任务 修改任务、任务环节状态  待任务调度执行
	 * @param msgBuilder
	 * @param planPO
	 * @param taskList
	 */
	private void executeTask(StringBuilder msgBuilder, DmPlanPO planPO, List<DmTaskPO> taskList) {
		//遍历处理任务
		int dmPlanId = (int)planPO.getDmPlanId();
		for (DmTaskPO taskPO : taskList) {
			//任务数判断处理 || 系统自动执行任务处理
			if (isMostTask(msgBuilder, taskPO) || isDoAutoTask(msgBuilder, taskPO) || isSysPausetask(msgBuilder, taskPO) 
					|| isPendingOrProsessingTask(msgBuilder, taskPO) || isCleanUpForOperType(msgBuilder,  planPO, taskPO)) {
				continue;
			}
			if (isStopTask(taskPO)){
				//暂停
				dealStopTask(msgBuilder, taskPO);
			}else if(isFailTask(taskPO)){
				//失败
				dealFailTask(msgBuilder, taskPO, planPO);
			}else{
				//手工
				dealHandTask(msgBuilder, dmPlanId, taskPO);
			}
		}
	}
/**
 * 处理手工任务部分
 * @param msgBuilder
 * @param dmPlanId
 * @param taskPO
 */
	private void dealHandTask(StringBuilder msgBuilder, int dmPlanId, DmTaskPO taskPO) {
		List<DmTaskPO> handTaskList = dmTaskDao.selectTaskForCreateHandTask(taskPO.getPriority(), dmPlanId, taskPO.getDmTaskId());
		if(Utils.isEmpty(handTaskList)){
			msgBuilder.append("该任务的状态不是暂停或者失败，不能执行启动操作!;");
		}else{
			for (DmTaskPO dmTaskPO : handTaskList) {
					if (isSuccOrRecOrCancleTask(msgBuilder, taskPO) || isNeedSubTask(msgBuilder, dmTaskPO)) {
						continue;
					}
					doHandTask(msgBuilder, dmPlanId, dmTaskPO);
			}
		}
	}

	private void doHandTask(StringBuilder msgBuilder, int dmPlanId,
			DmTaskPO dmTaskPO) {
		try {
			List<DmPlanRelationPO> relaList = dmPlanRelationDao.selectByEditPlan(dmPlanId, getHandTaskGroup(dmTaskPO.getPriority(), dmPlanId));
			if(Utils.isEmpty(relaList)){
				msgBuilder.append("任务【").append(dmTaskPO.getName()).append("】启动成功!;");
			}else{
				logger.debug("修改新增策略组"+relaList);
				msgBuilder.append(dmHandTask.initTableName(dmPlanId, relaList));
			}
			logger.debug("手动生成下一周期任务："+dmTaskPO.getDmTaskId()+"||count||"+dmTaskPO.getName()+"启动时间："+DateUtils.getCurrentDate());
			dmTaskService.addCreateHandTask(dmTaskPO.getDmTaskId());
		} catch (BaseAppException e) {
			logger.debug("生成子任务失败：报错信息为" + e);
			msgBuilder.append("生成子任务失败：报错信息为"+e+"!;");
		}
	}
	/**
	 * 处理失败的任务
	 * @param msgBuilder
	 * @param taskPO
	 */
	private void dealFailTask(StringBuilder msgBuilder, DmTaskPO taskPO,  DmPlanPO planPO) {
		List<DmTaskStagePO> stageList = new ArrayList<DmTaskStagePO>();
		List<String> stateList = null;
		stageList = dmTaskStageDao.selectCurrentState(taskPO.getDmTaskId(), taskPO.getState());
		logger.debug("state"+taskPO.getState().toString()+"查询待执行的任务环节表记录stageList"+stageList+DateUtils.getCurrentDate());
		if(Utils.isEmpty(stageList)){
			msgBuilder.append("任务【").append(taskPO.getName()).append("】的环节表不是失败状态，不能执行启动操作!;");
		}else{
			if(2==planPO.getSourceType()){
				stateList = dealFailFileStage(taskPO,stageList.get(0), planPO);
			}else{
				stateList = dealFailStage(taskPO,stageList.get(0));
			}
			//更新该条任务环节表的状态为待执行
			updateStageTable(taskPO.getDmTaskId(),DMSConstant.Status.PENDING.toString(), stateList, null);
			//更新任务表的状态为待执行
			updateTaskTable(taskPO.getDmTaskId(),DMSConstant.Status.PENDING.toString());
			msgBuilder.append("任务【").append(taskPO.getName()).append("】启动成功!;");
		}
	}
	/**
	 * 处理状态是暂停的任务
	 * @param msgBuilder
	 * @param taskPO
	 * @return
	 */
	private List<DmTaskStagePO> dealStopTask(StringBuilder msgBuilder,
			DmTaskPO taskPO) {
		/*
		 *  判断当前任务所处的环节
		 *  1、暂停时：
		 *  环节是体检--体检state='00A'、备份state='00A'、清理state='00A'，备份清理已完成，并生成子任务；
		 *  环节是备份--体检state='00A'、备份state='00T'，清理state='00T'，继续备份
		 *  环节是清理--体检state='00A'、备份state='00A'、清理state='00T'，继续清理
		 */
		List<DmTaskStagePO> stageList = new ArrayList<DmTaskStagePO>();
		stageList = dmTaskStageDao.selectCurrentState(taskPO.getDmTaskId(), DMSConstant.Status.PENDING.toString());
		if(Utils.isEmpty(stageList)){
			logger.debug("启动只更改任务表状态，环节表执行状态都不是待执行"+stageList.size());
			updateTaskTable(taskPO.getDmTaskId(),DMSConstant.Status.SUCCESS.toString());//00A
		}else{
			updateTaskTable(taskPO.getDmTaskId(), DMSConstant.Status.PENDING.toString());//00T
			setTaskStateForMem(taskPO.getDmTaskId());
		}
		msgBuilder.append("任务【").append(taskPO.getName()).append("】启动成功!;");
		return stageList;
	}

	private boolean isCleanUpForOperType(StringBuilder msgBuilder, DmPlanPO planPO, DmTaskPO taskPO) {
		if (isStopTask(taskPO) && DMSConstant.OPER_TYPE_CLEANUP == planPO.getOperType()) {			
			msgBuilder.append("计划【").append(planPO.getPlanName()).append("】只有体检环节，不能执行启动操作!;");
			return true;
		}
		return false;
	}


	private boolean isSuccOrRecOrCancleTask(StringBuilder msgBuilder, DmTaskPO dmTaskPO) {
			if ("00A".equals(dmTaskPO.getState())||"00S".equals(dmTaskPO.getState())||"00C".equals(dmTaskPO.getState())) {			
				return false;
			}
			msgBuilder.append("任务【").append(dmTaskPO.getName()).append("】未执行完成，不能手动生成任务!;");
			return true;
	}

	private boolean isNeedSubTask(StringBuilder msgBuilder, DmTaskPO dmTaskPO) {
		if ("T".equals(dmTaskPO.getNeedSubtask())) {			
			msgBuilder.append("任务【").append(dmTaskPO.getName()).append("】还有子任务未完成，不能手动生成任务!;");
			return true;
		}
		return false;
	}

	private String getHandTaskGroup(int priority, int dmPlanId) {
		String groupStr;
		List<Integer> groupList = new ArrayList<Integer>();
		List<DmTaskPO> task = dmTaskDao.selectEditTask(priority, dmPlanId);
		for (DmTaskPO dmTasklist : task) {
			groupList.add(dmTasklist.getGroupNbr());
		}
		groupStr = "("+Utils.convertIdList2Integer(groupList)+")";
		return groupStr;
	}
	/**
	 *待执行 执行中
	 * @param msgBuilder
	 * @param taskPO
	 * @return
	 */
	private boolean isPendingOrProsessingTask(StringBuilder msgBuilder, DmTaskPO taskPO) {
		if (DMSConstant.Status.PENDING.toString().equals(taskPO.getState())||
				DMSConstant.Status.PROCESSING.toString().equals(taskPO.getState())) {			
			msgBuilder.append("任务【").append(taskPO.getName()).append("】的状态不是暂停或者失败，不能执行启动操作!;");
			return true;
		}
		return false;
	}

	/**
	 * 系统暂停
	 * @param msgBuilder
	 * @param taskPO
	 * @return
	 */
	private boolean isSysPausetask(StringBuilder msgBuilder, DmTaskPO taskPO) {
		if (DMSConstant.Status.SYSPAUSE.toString().equals(taskPO.getState())) {			
			msgBuilder.append("系统暂停,不允许手工执行启动操作!;");
			return true;
		}
		return false;
	}
	
	/**
	 * 处理失败的环节记录
	 * @param taskPO
	 * @param stagePO
	 * @return
	 */
	private List<String> dealFailStage(DmTaskPO taskPO,
			DmTaskStagePO stagePO) {
		List<String> stateList  = new ArrayList<String>();
		stateList.add(DMSConstant.Status.FALSE.getState());
		//更新体检结果表的状态为00B,00C
		DmArg dmArg = new DmArg();
		DmPO po = new DmPO();
		DmArg.DmCriteria dmArgCri = dmArg.createCriteria();
		dmArgCri.andDmTaskIdEqualTo(taskPO.getDmTaskId());
		//失败启动
		if(stagePO.getStage()==0){
		        //1、将已体检出的结果明细删除，变更任务状态为待执行
				dmDao.deleteByArg("dm_"+stagePO.getCheckObjName(), dmArg);
		}else{
			if(stagePO.getStage()==1){
				//2、将失败的结果明细状态变更为待备份状态，变更任务状态为待执行
				dmArgCri.andStateEqualTo("0BF");
				po.setState("00B");
			}else if(stagePO.getStage()==2){
				//3、将失败的结果明细状态变更为待清理状态，变更任务状态为待执行
				dmArgCri.andStateEqualTo("0CF");
				po.setState("00C");
			}
			po.setErrorDesc(null);
			po.setStateDate(new Date());
			dmDao.updateBySctArg("dm_"+stagePO.getCheckObjName(), po, dmArg);
		}
		return stateList;
	}
	
	private List<String> dealFailFileStage(DmTaskPO taskPO, DmTaskStagePO stagePO, DmPlanPO planPO) {
		List<String> stateList  = new ArrayList<String>();
		stateList.add(DMSConstant.Status.FALSE.getState());
		//更新体检结果表的状态为00B,00C
		DmFDetailArg dmFDetailArg = new DmFDetailArg();
		DmFDetailPO po = new DmFDetailPO();
		DmFDetailArg.DmFDetailCriteria  dmFDetailArgCri = dmFDetailArg.createCriteria();
		int infoId = 0;
		if(stagePO.getStage()==0){
			infoId = stagePO.getDmInfoId();
		}else if(stagePO.getStage() ==1){
			infoId = stagePO.getDmInfoId() - 1;
		}else{
			infoId = stagePO.getDmInfoId() - 2;
		}
		List<DmFPO> dfList = dmFDao.selectByDmInfoId("dm_f_"+stagePO.getDmStrategyId(), infoId);
		for (DmFPO dmFPO : dfList) {
			dmFDetailArgCri.andTrackIdEqualTo(dmFPO.getTrackId());
			//失败启动
			if(stagePO.getStage()==0){
				//1、将已体检出的结果明细删除，变更任务状态为待执行
				dmFDetailDao.deleteByArg("dm_f_detail_"+stagePO.getDmStrategyId(), dmFDetailArg);
			}else{
				if(stagePO.getStage()==1){
					//2、将失败的结果明细状态变更为待备份状态，变更任务状态为待执行
					dmFDetailArgCri.andStateEqualTo("0BF");
					po.setState("00B");
				}else if(stagePO.getStage()==2){
					//3、将失败的结果明细状态变更为待清理状态，变更任务状态为待执行
					dmFDetailArgCri.andStateEqualTo("0CF");
					po.setState("00C");
				}
				po.setStateDate(new Date());
				dmFDetailDao.updateBySctArg("dm_f_detail_"+stagePO.getDmStrategyId(), po, dmFDetailArg);
			
			
		}
		}
		return stateList;
	}
	/**
	 * 更新内存中任务的状态
	 * @param dmtaskId
	 */
	private void setTaskStateForMem(int  dmtaskId) {
		TaskNotify notify = new TaskNotify();
		if(Utils.isEmpty(DMSConstant.taskInstList.get(dmtaskId))){
			notify.setStatus(DMSConstant.Status.PENDING.toString());
			DMSConstant.taskInstList.put(dmtaskId,notify);
		}else{
			DMSConstant.taskInstList.get(dmtaskId).setStatus(DMSConstant.Status.PENDING.toString());
		}
	}

	/**
	 * 系统自动执行任务处理
	 * 审批拒绝任务更新状态待任务调度执行处理
	 * @param msgBuilder
	 * @param taskPO
	 * @return
	 */
	private boolean isDoAutoTask(StringBuilder msgBuilder, DmTaskPO taskPO) {
		if (Util.isAutoTask(taskPO.getPriority())) {
			logger.info("任务[{0}]为自动执行任务...", taskPO.getDmTaskId());
			/*if (taskExecchildThreadService.isInBusTime()) {
				msgBuilder.append("当前时间处于营业时间内，执行系统自动归档任务【").append(taskPO.getDmTaskId()).append("】可能影响生产营业，暂不允许启动任务!;");						
			} else*/ 
			if (DMSConstant.CHECK_REFUSED == (int)taskPO.getIsCheck()){
				//TODO 可以启动、更新任务环节表、任务表审批状态为待审核即可
				taskPO.setState(DMSConstant.Status.PENDING.getState());
				taskPO.setIsCheck(DMSConstant.CHECK_WAITING);
				dmTaskDao.updateByPrimaryKey(taskPO);
				dmTaskStageCustomDao.updateStageByTaskId(taskPO.getDmTaskId());
				logger.info("任务[{0}]启动成功,待任务调度执行!;...", taskPO.getDmTaskId());
				msgBuilder.append("执行系统自动归档任务【").append(taskPO.getDmTaskId()).append("】启动成功,待任务调度执行!;");						
				return true;
			} else {
				return false;			
			}
		}
		return false;
	}

	/**
	 * 执行中任务是否达到最大数
	 * @param msgBuilder
	 * @param taskPO
	 * @return
	 */
	private boolean isMostTask(StringBuilder msgBuilder, DmTaskPO taskPO) {
		DmTaskArg arg = new DmTaskArg();
		arg.createCriteria().andStateEqualTo(DMSConstant.Status.PROCESSING.getState());
		int count = dmTaskDao.countByArg(arg).get(0);
		int maxTaskCount = Integer.valueOf(sysParamDao.selectByParamName("MAX_TASK_NUM").getParamValue());
		if (maxTaskCount - count <= 0) {
			msgBuilder.append("暂无空闲线程可执行任务，启动的任务【").append(taskPO.getDmTaskId()).append("】将进入等待运行状态!;");
			return true;
		}
		return false;
	}

	private boolean isFailTask(DmTaskPO taskPO) {
		return DMSConstant.Status.FALSE.getState().equals(taskPO.getState());
	}

	/**
	 * 是否是暂停中任务
	 * @param taskPO
	 * @return
	 */
	private boolean isStopTask(DmTaskPO taskPO) {
		return DMSConstant.Status.PAUSE.getState().equals(taskPO.getState())||
			DMSConstant.Status.DELAYPAUSE.getState().equals(taskPO.getState());
	}

	/**
	 * 判断有没有执行数据恢复
	 * @param msgBuilder
	 * @param planPO
	 */
	private boolean isDoRecovery(StringBuilder msgBuilder, DmPlanPO planPO) {
		DmDataStatePO ddsPO = dmDataStateDao.selectByPrimaryKey(planPO.getDmPlanId());
		if (Utils.notEmpty(ddsPO) && Util.isRecovery(ddsPO.getState())) {
			logger.info("该计划[{0}]执行数据恢复无法启动",planPO.getDmPlanId());
			msgBuilder.append("计划【").append(planPO.getPlanName()).append("】的任务进行了数据恢复操作，需要到\"数据恢复页\"进行对数据恢复工作的人工确认后才可继续启动！;");
			return true;
		}
		return false;
	}

	/**
	 * 如果查询任务为空且计划为手工执行、则生成任务
	 * @param msgBuilder
	 * @param planPO
	 * @return
	 */
	private List<DmTaskPO> getTaskList(StringBuilder msgBuilder, DmPlanPO planPO) {
		List<DmTaskPO> taskList = dmTaskDao.selectTaskPOByPlanIdStart(planPO.getDmPlanId());
		if(Utils.isEmpty(taskList) && Util.isHanderTask(planPO.getExecType())){
			logger.info("计划[{0}首次生成手工任务...",planPO.getDmPlanId());
			msgBuilder.append(dmHandTask.initTableName(planPO.getDmPlanId(), null));
			logger.info("计划{0}首次生成手工任务ok...",planPO.getDmPlanId());
			taskList = dmTaskDao.selectTaskPOByPlanIdStart(planPO.getDmPlanId());
		}
		return taskList;
	}

	/**
	 * 判断计划是否有效 即~计划是否在生失效范围内
	 * @param msgBuilder
	 * @param planPO
	 * @return
	 */
	private boolean isValid(StringBuilder msgBuilder, DmPlanPO planPO) {
		//判断生失效时间
		if(DateUtils.isInRange(new Date(), planPO.getEffDate(), planPO.getExpDate())){
			return true;
		}
		logger.info("该计划[{0}]不在生失效时间内无法启动",planPO.getDmPlanId());
		msgBuilder.append("计划【").append(planPO.getPlanName()).append("】不在生失效时间内无法启动!;");
		return false;
	}

	//更新任务环节表的状态
	private void updateStageTable(Integer dmTaskId,String stageStage, List<String> stateWhere, Integer dmInfoId) {
		DmTaskStagePO po = new DmTaskStagePO();
		DmTaskStageArg art = new DmTaskStageArg();
		DmTaskStageArg.DmTaskStageCriteria stagec = art.createCriteria();
		stagec.andDmTaskIdEqualTo(dmTaskId);
		stagec.andStateIn(stateWhere);
		if(!Utils.isEmpty(dmInfoId)){
			stagec.andStageEqualTo(dmInfoId);
		}
		po.setState(stageStage);
		po.setStateDate(new Date());
		dmTaskStageDao.updateByArgSelective(po,art);
	}
	//更新任务表的状态
	private void updateTaskTable(Integer dmTaskId, String state) {
		DmTaskArg art = new DmTaskArg();
		DmTaskArg.DmTaskCriteria task = art.createCriteria();
		task.andDmTaskIdEqualTo(dmTaskId);
		DmTaskPO po = new DmTaskPO();
		po.setState(state);
		po.setStateDate(new Date());
		dmTaskDao.updateByArgSelective(po,art);
	}
	/**
	 * 立即暂停
	 * 
	 * @param dmPlanIds
	 */
	@Override
	public List<String> immediatelyPause(String dmPlanIdStr) {
		Integer dmPlanId;
		StringBuilder msgBuilder = new StringBuilder();
		// 获取list id
		List<String> dmPlanIdList = Utils.convertIdString2ListByComma(dmPlanIdStr);
		logger.debug("任务监控界面点击立即暂停按钮产生操作||"+dmPlanIdList);
		for (String dmPlanIds : dmPlanIdList) {
			dmPlanId = Integer.valueOf(dmPlanIds);
//			List<DmTaskPO> taskList = dmTaskDao.selectTaskPOByPlanIdPause(dmPlanId);
			List<DmTaskPO> taskList = dmTaskDao.selectTaskPOByPlanIdStart(dmPlanId);
			DmPlanPO planPO = dmPlanDao.selectByPrimaryKey(dmPlanId);
			if (!Utils.isEmpty(planPO)) {
				if (planPO.getOperType() != 2) {
					if (!Utils.isEmpty(taskList)) {
						//taskPO = taskList.get(0);
						for (DmTaskPO taskPO : taskList) {
							logger.debug("当前任务环节状态"+taskPO.getState());
							if ("00R".equals(taskPO.getState())) {
								// 判断当前任务所处的环节
								List<DmTaskStagePO> stageList = dmTaskStageDao.selectCurrentState(taskPO.getDmTaskId(), "00R");
								if(Utils.isEmpty(stageList)){
									msgBuilder.append("任务【").append(taskPO.getName()).append("】的环节表不是执行中状态，不能执行暂停操作!;");
								}else{
									logger.debug("获取当前执行中任务所处在的环节" + stageList.get(0).getStage());
									DmTaskArg art = new DmTaskArg();
									DmTaskPO po = new DmTaskPO();
									DmTaskArg.DmTaskCriteria taskd = art.createCriteria();
									po.setState("0DP");
									taskd.andDmTaskIdEqualTo(taskPO.getDmTaskId());
									dmTaskDao.updateByArgSelective(po, art);
									
									TaskNotify notify = new TaskNotify();
									notify.setStatus("00P");
									DMSConstant.taskInstList.put(taskPO.getDmTaskId(), notify);
									msgBuilder.append("任务【").append(taskPO.getName()).append("】立即暂停成功!;");
								} 
							}else{
								msgBuilder.append("任务【").append(taskPO.getName()).append("】的状态只有执行中才能立即暂停，请确认后操作!;");
							}
						}
					}else{
						msgBuilder.append("计划【").append(planPO.getPlanName()).append("】下的任务数据异常，请和管理员确认!;");
					}
				}else{
					msgBuilder.append("计划【").append(planPO.getPlanName()).append("】仅执行“体检”，无暂停操作!;");
				}
			}else{
				msgBuilder.append("该计划【").append(planPO.getPlanName()).append("】下的任务数据异常，请和管理员确认!;");
			}
		}
		return stringToList(msgBuilder.toString());
	}

	@Override
	public List<String> delayPause(String dmPlanIdStr) {
		Integer dmPlanId;
		StringBuilder msgBuilder = new StringBuilder();
		// 获取list id
		List<String> dmPlanIdList = Utils.convertIdString2ListByComma(dmPlanIdStr);
		logger.debug("任务监控界面点击延时暂停按钮产生操作||"+dmPlanIdList);
		for (String dmPlanIds : dmPlanIdList) {
			dmPlanId = Integer.valueOf(dmPlanIds);
			List<DmTaskPO> taskList = dmTaskDao.selectTaskPOByPlanIdStart(dmPlanId);
			logger.debug("延时暂停taskListsize"+taskList.size());
			DmPlanPO planPO = dmPlanDao.selectByPrimaryKey(dmPlanId);
			List<String> stateList = new ArrayList<String>();
			if (planPO.getOperType() != 2) {
				if (!Utils.isEmpty(taskList)) {
					for (DmTaskPO taskPO : taskList) {
						//taskPO = taskList.get(0);
						logger.debug("当前任务环节状态"+taskPO.getState());
						if ("00R".equals(taskPO.getState())) {
							// 判断当前任务所处的环节
							List<DmTaskStagePO> stageList = dmTaskStageDao.selectCurrentState(taskPO.getDmTaskId(),"00R");
							
							if(Utils.isEmpty(stageList)){
								msgBuilder.append("任务【").append(taskPO.getName()).append("】的环节表不是执行中状态，不能执行启动操作!;");
							}else{
								
								if(isDelayTask(stageList.get(0).getDmTaskId(), stageList.get(0).getDmStrategyId())){
									logger.debug("获取当前执行中任务所处在的环节" + stageList.get(0).getStage());
									DmTaskArg art = new DmTaskArg();
									DmTaskPO po = new DmTaskPO();
									DmTaskArg.DmTaskCriteria taskd = art.createCriteria();
									taskd.andDmPlanIdEqualTo(taskPO.getDmPlanId());
									taskd.andDmTaskIdEqualTo(stageList.get(0).getDmTaskId());
									po.setState("0DP");
									po.setStateDate(new Date());
									dmTaskDao.updateByArgSelective(po, art);
									// 读取共享内存信息，写入“01P”
									/*
									 * DMSConstant.taskInstList.get(taskPO.getDmTaskId())
									 * .setStatus("01P");
									 */
									TaskNotify notify = new TaskNotify();
									notify.setStatus("01P");
									DMSConstant.taskInstList.put(taskPO.getDmTaskId(),notify);
									msgBuilder.append("任务【").append(taskPO.getName()).append("】延时暂停成功!;");
								}else{
									msgBuilder.append("该任务【").append(taskPO.getName()).append("】正在执行最后一个策略，不能执行延时暂停!;");
								}
							} 
						}else{
							msgBuilder.append("任务【").append(taskPO.getName()).append("】的状态只有执行中才能延时暂停，请确认后操作!;");
						}
					}
				}else{
					msgBuilder.append("该计划【").append(planPO.getPlanName()).append("】下的任务数据异常，请和管理员确认!;");
				}

			} else {
				msgBuilder.append("计划【").append(planPO.getPlanName()).append("】仅执行“体检”，无暂停操作!;");
			}

		}
		return stringToList(msgBuilder.toString());

	}
	@Override
	public List<String> clickCaTask(String dmPlanIdStr) {
		Integer dmPlanId;
 		StringBuilder msgBuilder = new StringBuilder();
 		for (String dmPlanIds : Utils.convertIdString2ListByComma(dmPlanIdStr)) {
			dmPlanId = Integer.valueOf(dmPlanIds);
			DmPlanPO planPO = dmPlanDao.selectByPrimaryKey(dmPlanId);
			if(planPO.getOperType()!=2){
				// 写入共享内存中的任务线程列表
				List<DmTaskPO> taskList = dmTaskDao.selectTaskPOByPlanIdStart(dmPlanId);
				logger.debug("取消taskList"+taskList.size());
				if (taskList != null && taskList.size() > 0) {
					for (DmTaskPO dmTaskPO : taskList) {
						if(1==planPO.getSourceType()){//表
							msgBuilder = celTableTask(dmTaskPO);
						}else{
							msgBuilder = celFileTask(dmTaskPO);//文件
							
						}
					}
				//	
				}else{
					msgBuilder.append("该计划下的任务数据异常，请和管理员确认!;");
				}
			}else{
				msgBuilder.append("计划【").append(planPO.getPlanName()).append("】仅执行“体检”，无取消操作!;");
			}
		}
 		return stringToList(msgBuilder.toString());
	}

	public StringBuilder celTableTask(DmTaskPO dmTaskPO) {
		DmArg dmarg;
		DmArg.DmCriteria criteria;
		StringBuilder msgBuilder = new StringBuilder();
		List<DmTaskStagePO> stageList = new ArrayList<DmTaskStagePO>();
		if (DMSConstant.Status.PENDING.toString().equals(dmTaskPO.getState())
				|| "00R".equals(dmTaskPO.getState()) || "00F".equals(dmTaskPO.getState())) {// 增加失败取消
			DmTaskArg art = new DmTaskArg();
			DmTaskPO po = new DmTaskPO();
			DmTaskArg.DmTaskCriteria taskd = art.createCriteria();
			if (DMSConstant.Status.PENDING.toString().equals(dmTaskPO.getState())) {
				logger.debug("取消待执行任务" + dmTaskPO.getDmTaskId() + "||" + DateUtils.getCurrentDate());
				po.setState("00C");
				po.setStateDate(new Date());
				po.setNeedSubtask("F");
				po.setIsCheck(0);
				taskd.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
				//
				DmTaskStageArg arg = new DmTaskStageArg();
				DmTaskStageArg arg1 = new DmTaskStageArg();
				DmTaskStageArg.DmTaskStageCriteria stagec = arg.createCriteria();
				DmTaskStageArg.DmTaskStageCriteria staged = arg1.createCriteria();
				stagec.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
				stagec.andStateNotEqualTo(DMSConstant.Status.PENDING.toString());
				stagec.andStageEqualTo(0);// 体检
				stageList = dmTaskStageDao.selectByArg(arg);
				if (!Utils.isEmpty(stageList)) {
					for (DmTaskStagePO stage : stageList) {
						dmarg = new DmArg();
						criteria = dmarg.createCriteria();
						criteria.andDmTaskIdEqualTo(stage.getDmTaskId());
						criteria.andDmStrategyIdEqualTo(stage.getDmStrategyId());
						dmDao.deleteByArg("dm_" + stage.getCheckObjName(), dmarg);
					}
				}
				staged.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
				staged.andStateEqualTo(DMSConstant.Status.PENDING.toString());
				stageList = dmTaskStageDao.selectByArg(arg1);
				for (DmTaskStagePO dmTaskStagePO : stageList) {
					dmTaskStagePO.setState("00X");
					dmTaskStageDao.updateByPrimaryKeySelective(dmTaskStagePO);
				}
			} else if ("00F".equals(dmTaskPO.getState())) {// 失败取消、、
				stageList = dmTaskStageDao.selectCurrentState(dmTaskPO.getDmTaskId(), "00F");
				// 失败启动
				dmarg = new DmArg();
				if (stageList.get(0).getStage() == 0) {
					// 1、体检
					// 将已体检出的结果明细删除，变更任务状态为作废00X，备注为“任务失败后取消”；所有任务环节记录状态为00C。
					dmDao.deleteByArg("dm_" + stageList.get(0).getCheckObjName(), dmarg);
				} else if (stageList.get(0).getStage() == 1) {
					// 2、备份
					// 将已备份成功的数据从目标库删除，并且删除结果明细表记录，变更任务环节表状态为00C，任务表状态为作废00X。
					deleteBackData(stageList);
					dmDao.deleteByArg("dm_" + stageList.get(0).getCheckObjName(), dmarg);

				} else if (stageList.get(0).getStage() == 2) {
					// 3、清理
					// 将后续未清理的数据，从目标库删除，已清理的数据不处理。变更任务环节表状态为00C和任务表状态为作废00X。
					String dmTableName = "DM_"+stageList.get(0).getCheckObjName();;
					dmDao.updateByLimit(dmTableName, "00C", DateUtils.getDBCurrentTime(), stageList.get(0).getDmTaskId(), 
							stageList.get(0).getDmStrategyId(), "0CF", 1000, null);
					// 执行删除并更新任务环节表
					try {
						cleanUpService.cleanUp(stageList.get(0).getDmTaskId(), stageList.get(0).getDmStrategyId(), 4);
					} catch (BaseAppException e) {
						logger.debug("取消清理失败的任务：" + e);
					}
				}
				// 更新该条任务环节表的状态为作废
				List<DmTaskStagePO> statelist = dmTaskStageDao .selectCurrentMultiState(dmTaskPO.getDmTaskId(),
								new String[] { "00T", "00F" });
				for (DmTaskStagePO dmTaskStagePO : statelist) {
					dmTaskStagePO.setState("00X");
					dmTaskStageDao.updateByPrimaryKeySelective(dmTaskStagePO);
				}

				po.setState("00C");
				po.setStateDate(new Date());
				po.setNeedSubtask("F");
				po.setIsCheck(0);
				po.setErrorDesc("任务失败后取消");
				taskd.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
			} else {
				// 判断当前执行的是否是清理状态
				// 判断当前任务所处的环节
				stageList = dmTaskStageDao.selectCurrentState(
						dmTaskPO.getDmTaskId(), "00R");
				if (stageList.get(0).getStage() == 2) {
					msgBuilder.append("任务【" + dmTaskPO.getName() + "】正在执行清理操作，不允许取消操作!;");
					// break; //FIXME
				} else {
					po.setState("0DC");
					po.setStateDate(new Date());
					po.setNeedSubtask("F");
					taskd.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
				}
			}
			dmTaskDao.updateByArgSelective(po, art);
			TaskNotify notify = new TaskNotify();
			notify.setStatus("00C");
			DMSConstant.taskInstList.put(dmTaskPO.getDmTaskId(), notify);
			msgBuilder.append("任务【" + dmTaskPO.getName() + "】取消成功!;");
			/*
			 * DMSConstant.taskInstList.get(dmTaskPO.getDmTaskId())
			 * .setStatus("00C");
			 */
		} else {
			msgBuilder.append("任务【").append(dmTaskPO.getName())
					.append("】状态只有待处理、执行中、失败才能取消，请确认后操作!;");
		}
		return msgBuilder;
	}
	public StringBuilder celFileTask(DmTaskPO dmTaskPO) {
//		DmArg dmarg;
//		DmArg.DmCriteria criteria;
		DmFDetailArg dmFDetailArg;
		DmFDetailArg.DmFDetailCriteria criteria;
		StringBuilder msgBuilder = new StringBuilder();
		List<DmTaskStagePO> stageList = new ArrayList<DmTaskStagePO>();
		if (DMSConstant.Status.PENDING.toString().equals(dmTaskPO.getState())
				|| "00R".equals(dmTaskPO.getState()) || "00F".equals(dmTaskPO.getState())) {// 增加失败取消
			DmTaskArg art = new DmTaskArg();
			DmTaskPO po = new DmTaskPO();
			DmTaskArg.DmTaskCriteria taskd = art.createCriteria();
			if (DMSConstant.Status.PENDING.toString().equals(dmTaskPO.getState())) {
				logger.debug("取消待执行任务" + dmTaskPO.getDmTaskId() + "||" + DateUtils.getCurrentDate());
				po.setState("00C");
				po.setStateDate(new Date());
				po.setNeedSubtask("F");
				po.setIsCheck(0);
				taskd.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
				//
				DmTaskStageArg arg = new DmTaskStageArg();
				DmTaskStageArg arg1 = new DmTaskStageArg();
				DmTaskStageArg.DmTaskStageCriteria stagec = arg.createCriteria();
				DmTaskStageArg.DmTaskStageCriteria staged = arg1.createCriteria();
				stagec.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
				stagec.andStateNotEqualTo(DMSConstant.Status.PENDING.toString());
				stagec.andStageEqualTo(0);// 体检
				stageList = dmTaskStageDao.selectByArg(arg);
				if (!Utils.isEmpty(stageList)) {
					for (DmTaskStagePO stage : stageList) {
						dealDmFTable(stage);		
					}
				}
				staged.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
				staged.andStateEqualTo(DMSConstant.Status.PENDING.toString());
				stageList = dmTaskStageDao.selectByArg(arg1);
				for (DmTaskStagePO dmTaskStagePO : stageList) {
					dmTaskStagePO.setState("00X");
					dmTaskStageDao.updateByPrimaryKeySelective(dmTaskStagePO);
				}
			} else if ("00F".equals(dmTaskPO.getState())) {// 失败取消、、
				stageList = dmTaskStageDao.selectCurrentState(dmTaskPO.getDmTaskId(), "00F");
				// 失败启动
				dmFDetailArg = new DmFDetailArg();
				if (stageList.get(0).getStage() == 0) {
					// 1、体检
					// 将已体检出的结果明细删除，变更任务状态为作废00X，备注为“任务失败后取消”；所有任务环节记录状态为00C。
					//dmDao.deleteByArg("dm_" + stageList.get(0).getCheckObjName(), dmarg);
					dealDmFTable(stageList.get(0));
				} else if (stageList.get(0).getStage() == 1) {
					// 2、备份
					// 将已备份成功的数据从目标库删除，并且删除结果明细表记录，变更任务环节表状态为00C，任务表状态为作废00X。
					//FIXME
					//deleteBackData(stageList);
					dealDmFTable(stageList.get(0));
					//dmDao.deleteByArg("dm_" + stageList.get(0).getCheckObjName(), dmarg);

				} else if (stageList.get(0).getStage() == 2) {
					// 3、清理
					// 将后续未清理的数据，从目标库删除，已清理的数据不处理。变更任务环节表状态为00C和任务表状态为作废00X。
					//FIXME
				/*	String dmTableName = "DM_"+stageList.get(0).getCheckObjName();;
					dmDao.updateByLimit(dmTableName, "00C", DateUtils.getDBCurrentTime(), stageList.get(0).getDmTaskId(), 
							stageList.get(0).getDmStrategyId(), "0CF", 1000, null);
					// 执行删除并更新任务环节表
					try {
						cleanUpService.cleanUp(stageList.get(0).getDmTaskId(), stageList.get(0).getDmStrategyId(), 4);
					} catch (BaseAppException e) {
						logger.debug("取消清理失败的任务：" + e);
					}*/
				}
				// 更新该条任务环节表的状态为作废
				List<DmTaskStagePO> statelist = dmTaskStageDao .selectCurrentMultiState(dmTaskPO.getDmTaskId(),
								new String[] { "00T", "00F" });
				for (DmTaskStagePO dmTaskStagePO : statelist) {
					dmTaskStagePO.setState("00X");
					dmTaskStageDao.updateByPrimaryKeySelective(dmTaskStagePO);
				}

				po.setState("00C");
				po.setStateDate(new Date());
				po.setNeedSubtask("F");
				po.setIsCheck(0);
				po.setErrorDesc("任务失败后取消");
				taskd.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
			} else {
				// 判断当前执行的是否是清理状态
				// 判断当前任务所处的环节
				stageList = dmTaskStageDao.selectCurrentState(
						dmTaskPO.getDmTaskId(), "00R");
				if (stageList.get(0).getStage() == 2) {
					msgBuilder.append("任务【" + dmTaskPO.getName() + "】正在执行清理操作，不允许取消操作!;");
					// break; //FIXME
				} else {
					po.setState("0DC");
					po.setStateDate(new Date());
					po.setNeedSubtask("F");
					taskd.andDmTaskIdEqualTo(dmTaskPO.getDmTaskId());
				}
			}
			dmTaskDao.updateByArgSelective(po, art);
			TaskNotify notify = new TaskNotify();
			notify.setStatus("00C");
			DMSConstant.taskInstList.put(dmTaskPO.getDmTaskId(), notify);
			msgBuilder.append("任务【" + dmTaskPO.getName() + "】取消成功!;");
			/*
			 * DMSConstant.taskInstList.get(dmTaskPO.getDmTaskId())
			 * .setStatus("00C");
			 */
		} else {
			msgBuilder.append("任务【").append(dmTaskPO.getName())
					.append("】状态只有待处理、执行中、失败才能取消，请确认后操作!;");
		}
		return msgBuilder;
	}

	private void dealDmFTable(DmTaskStagePO stage) {
		DmFDetailArg dmFDetailArg;
		DmFDetailArg.DmFDetailCriteria criteria;
		List<DmFPO> dfList = dmFDao.selectByDmInfoId("dm_f_" + stage.getDmStrategyId(), stage.getDmInfoId());
		for (DmFPO dmFPO : dfList) {
			dmFDetailArg = new DmFDetailArg();
			criteria = dmFDetailArg.createCriteria();
			criteria.andDmTaskIdEqualTo(stage.getDmTaskId());
			criteria.andTrackIdEqualTo(dmFPO.getTrackId());
			dmFDetailDao.deleteByArg("dm_f_detail_" + stage.getDmStrategyId(), dmFDetailArg);
			
			dmFPO.setTotalRecordCount(0);
			dmFPO.setTotalRecordSize(BigDecimal.ZERO);
			dmFPO.setCheckDataCount(0);
			dmFPO.setCheckDataSize(BigDecimal.ZERO);
			dmFDao.updateByPrimaryKeySelective("dm_f_" + stage.getDmStrategyId(), dmFPO);
		}
	}
	/***
	 * 将已备份成功的数据从目标库删除
	 * @param stageList
	 */
	private void deleteBackData(List<DmTaskStagePO> stageList) {
		int i = 0;
		List<String> tableNameList = null ;
		Map<Integer, DmTaskStagePO> map = new HashMap<Integer, DmTaskStagePO>();
		DataSource targetTableDs = null;
		Connection targetTableCon = null;
		if(stageList.size()>0&&stageList!=null){
			for (DmTaskStagePO dmTaskStagePO : stageList) {
					map.put(dmTaskStagePO.getSourceDataId(), dmTaskStagePO);
			}
			for (Integer key : map.keySet()) {
					tableNameList = new ArrayList<String>();
				    System.out.println("key= "+ key + " and value= " + map.get(key));
					// 获取源表信息，用于判断是否是从表
					DmSrcTablePO dstPO = dmSrcTableDao.selectByPrimaryKey(map.get(key).getSourceDataId());
					DmStrategyPO dsPO = dmStrategyDao.selectByPrimaryKey(map.get(key).getDmStrategyId());
					//判断是否有分表要归档
					if (DMSConstant.ARCHIVE_TYPE_REL==dstPO.getArchiveType()) {
						List<DmSrcTablePO> subTable = srcTableCustomDao.selectByStrategyRef(dsPO.getDmStrategyId());
						for (DmSrcTablePO dmSrcTablePO : subTable) {
							DmTargetTablePO dttPO = dmTargetTableDao
									.selectBySourceId(dmSrcTablePO.getSourceDataId());
							tableNameList.add(dttPO.getTableName());
						}
					}
					// 获取目标表的信息：ID、数据库连接ID、数据库用户名
					DmTargetTablePO dttPO = dmTargetTableDao.selectBySourceId(map.get(key).getSourceDataId());
					tableNameList.add(dttPO.getTableName());
					String[] targetTableConfig;
					PreparedStatement targetTablePstmt = null;
					try {
						targetTableConfig = baseInfoService.getDbConfig(dttPO.getDbLinkId(), dttPO.getDbUserName());
						targetTableDs = dynamicDataSourceManager.getDruidDataSource(dttPO.getDbLinkId() + dttPO.getDbUserName(), targetTableConfig);
						targetTableCon = DataSourceUtils.getConnection(targetTableDs);
						if (DMSConstant.DB_LINK_CATEGORY_INFORMIX.equals(targetTableConfig[0].toUpperCase())) {
							targetTableCon.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
						}
						// 获取目标数据库类型
						DbBaseInfoPO dbiPO = dbBaseInfoDao.selectForDbType(dttPO
								.getDbLinkId());
						for (String tableName : Utils.removeDuplicate(tableNameList)) {
							StringBuilder targetTableDeleteSql = new StringBuilder();
							targetTableDeleteSql.append("delete from " + tableName + " where 1=1").append(" and dm_task_id=").append(map.get(key).getDmTaskId());
							targetTablePstmt = targetTableCon.prepareStatement(targetTableDeleteSql.toString());
							i = targetTablePstmt.executeUpdate();
							logger.info("任务取消，备份环节，删除目标表"+tableName +"总记录数为"+i+"条");
						}
					} catch (Exception e) {
						e.printStackTrace();
					} finally {
						JdbcUtils.closeStatement(targetTablePstmt);
						DataSourceUtils.releaseConnection(targetTableCon, targetTableDs);
					}
			}
		}
	}
	
	/**
     * 根据源对象拼接表名
     * @param baseName 基表名
     * @param subFlag 分表标识
     * @param dataId 对象标识
     * @param sourceDataPo 源对象
     * @param subMap 源对象值
     * @return
     */
    private String getTableName(String baseName,String subFlag,int dataId,int dataType,DmSrcTablePO sourceDataPo,Map<String ,Object> subMap){
		StringBuilder tableName = new StringBuilder();
		tableName.append(baseName);
		if(DMSConstant.SUB_FLAG_T.equals(subFlag)){
			//根据目标标识查找分表定义
			SubTableDefineArg subTableDefineArg = new SubTableDefineArg();
			SubTableDefineArg.SubTableDefineCriteria subTableDefineCriteria = subTableDefineArg.createCriteria();
			subTableDefineCriteria.andSourceDataIdEqualTo(dataId);
			subTableDefineCriteria.andDataTypeEqualTo(dataType);
			subTableDefineCriteria.andStateEqualTo(DMSConstant.Status.SUCCESS.toString());
			subTableDefineArg.setOrderByClause("priority");
			List<SubTableDefinePO> subTableDefineList = subTableDefineDao.selectByArg(subTableDefineArg);
			if(subTableDefineList.size()>1){
				for(int i=1;i<subTableDefineList.size();i++){
					SubTableDefinePO po = subTableDefineList.get(i);
					if(po.getSubDefineType()==DMSConstant.SUB_DEFINE_TYPE_FIXED){
						tableName.append("_"+po.getSubDefineValue());
					}else if(po.getSubDefineType()==DMSConstant.SUB_DEFINE_TYPE_CHANGE){
						Object subRefColValue =subMap.get(po.getSubRefCol());
						if(Utils.isEmpty(po.getSubDefineValue())){
							tableName.append("_"+String.valueOf(subRefColValue));
						}else{
							switch (Integer.parseInt(po.getSubDefineValue())) {
								case 2:
									tableName.append("_"+exchangeFunc.yearMonthExchange((Date)subRefColValue));
									break;
								case 3:
									tableName.append("_"+exchangeFunc.dateExchange((Date)subRefColValue));
									break;
								case 4:
									tableName.append("_"+exchangeFunc.billingCycleExchange((Date)subRefColValue));
									break;
								default:
									tableName.append("_"+String.valueOf(subRefColValue));
									break;
							}
						}
					}
				}
			}
		}
		return tableName.toString();
	}
	private Integer selectCountTask(DmTaskStagePO record, List<String> state) {
		DmTaskArg taskArg = new DmTaskArg();
		taskArg.setCountsql1("SELECT count(a.DM_TASK_ID) FROM DM_TASK a left join dm_plan b on a.DM_PLAN_ID = b.dm_plan_id ");
		DmTaskCriteria taskCriteria = taskArg.createCriteria();
		taskCriteria.andStateBEqualTo("00A");

		if (Utils.notEmpty(record.getScheduleDate())) {
			// criteria.andScheduleDateBetween(record.getScheduleDate(),
			// record.getScheduleDate());
		}
		if (Utils.notEmpty(record.getNodeId())) {
			taskCriteria.andNodeIdAEqualTo(record.getNodeId());
		}
		if (Utils.notEmpty(record.getPlanName())) {
			taskCriteria.andPlanNameBEqualTo(record.getPlanName());
		}

		taskCriteria.andStateAIn(state);
		int count = dmTaskDao.countByArg(taskArg).get(0);
		return count;
	}

	@Override
	public Integer[] countPauseTask(DmTaskStagePO record) {
		Integer[] counts = new Integer[5];

		List<String> stateList = new ArrayList<String>();

		// 执行中
		stateList.clear();
		stateList.add("00R");
		int rCount = selectCountTask(record, stateList);

		// 待执行
		stateList.clear();
		stateList.add("00T");
		int tCount = selectCountTask(record, stateList);

		// 执行完成
		stateList.clear();
		stateList.add("00A");
		int aCount = selectCountTask(record, stateList);
		// 执行失败
		stateList.clear();
		stateList.add("00F");
		int fCount = selectCountTask(record, stateList);

		// 暂停
		stateList.clear();
		stateList.add("00P");
		stateList.add("01P");
		stateList.add("02P");
		int pCount = selectCountTask(record, stateList);

		counts[0] = rCount;
		counts[1] = tCount;
		counts[2] = aCount;
		counts[3] = fCount;
		counts[4] = pCount;

		return counts;
	}

	@Override
	public List<DmPO> qryLeftErrorInfo(String dmInfoId, String state) {
		Integer infoId = Integer.valueOf(dmInfoId);
		DmTaskStagePO stagePO = dmTaskStageDao.selectByPrimaryKey(infoId);
		Integer dmTaskId = stagePO.getDmTaskId();
		String tableName = "DM_" + stagePO.getCheckObjName();
		return dmDao.qryLeftErrorInfo(tableName, dmTaskId, state);
	}

	@Override
	public List<DmPO> qryRightErrorInfo(String dmInfoId, String state) {
		Integer infoId = Integer.valueOf(dmInfoId);
		DmTaskStagePO stagePO = dmTaskStageDao.selectByPrimaryKey(infoId);
		Integer dmTaskId = stagePO.getDmTaskId();
		String tableName = "DM_" + stagePO.getCheckObjName();
		return dmDao.qryRightErrorInfo(tableName, dmTaskId, state);
	}
	@Override
	public List<DmFPO> qryLeftErrorInfoFile(String dmInfoId, String state) {
		Integer infoId = Integer.valueOf(dmInfoId);
		DmTaskStagePO stagePO = dmTaskStageDao.selectByPrimaryKey(infoId);
		Integer dmTaskId = stagePO.getDmTaskId();
		String tableName = "DM_F_" + stagePO.getDmStrategyId();
		return dmFDao.qryLeftErrorInfoFile(tableName, dmTaskId, state);
	}

	@Override
	public List<DmFPO> qryRightErrorInfoFile(String dmInfoId, String state) {
		Integer infoId = Integer.valueOf(dmInfoId);
		DmTaskStagePO stagePO = dmTaskStageDao.selectByPrimaryKey(infoId);
		Integer dmTaskId = stagePO.getDmTaskId();
		String tableName = "DM_F_" + stagePO.getDmStrategyId();
		return dmFDao.qryRightErrorInfoFile(tableName, dmTaskId, state);
	}
	
	private List<String> stringToList(String str){
		return Utils.convertIdString2ListByComma(str, ";");
	}

	private boolean isDelayTask(Integer dmTaskId, Integer dmStategyId) {
		boolean flag = true;
		List<DmTaskStagePO> strategyList = dmTaskStageDao.selectNextStrategy(dmTaskId, "00T", dmStategyId);
		if(Utils.isEmpty(strategyList)){
			flag =  false;
		}
		return flag;
	}

	@Override
	public Integer[] selectStateCount(Integer dmTaskId) {
		Integer[] counts = new Integer[5];
		DmTaskStagePO stagePO = dmTaskStageDao.selectStateCount(dmTaskId);
		counts[0] = stagePO.getTotal();
		counts[1] = stagePO.getaCount();
		counts[2] = stagePO.getrCount();
		counts[3] = stagePO.gettCount();
		counts[4] = stagePO.getfCount();
		return counts;
	}

}
